#include "daq.h"
#include "util/util.h"
#include <stdio.h>

using namespace DAQ_namespace;

extern DAQALLOC DAQ;

extern EVENT_HANDLE eh;
extern DWORD eventMsk;
extern DWORD eventWord;

extern pthread_t primary;  //this is the primary thread.  The program state machine exists here
extern pthread_t receive;  //this thread handles and buffers incoming Rx data

//simple function used to report packet lengths
uint16_t packetSizeLookup(uint8_t msgHeader)
{

    /*
     *Originally all message types were polled using sizeof.  Such a method would return the byte lenght.
     *Unfortunately the current version of mingw has a bug in sizeof.  sizeof inquries to bitfield objects
     *Return erroneous lengths.  As a result all static values have been hard coded.
    */

    switch(msgHeader)
    {
        //general messages
        case ack_mh:
            return	6;
        break;
        case resetDaq_mh:
            return	4;
        break;
        case startProgram_mh:
            return	4;
        break;
        case stopProgram_mh:
            return	4;
        break;
        case daqReady_mh:
            return	4;
        break;
        //adc messages
        case adcInit_mh:
            return	6;
        break;
        //dac messages
        case dacEnable_mh:
            return	5;
        break;
        //dio messages
        case (digitalInEnable_mh):
            return	4;
        break;
        case (digitalOutEnable_mh):
            return	4;
        break;
        //encoder messages
        case encInit_mh:
            return	7;
        break;
        //pwm messages
        case (servoEnable_mh):
            return 5;
        break;
        case (motorEnable_mh):
            return 5;
        break;
        //tmr messages
        case (tmrSetFreq_mh):
            return 6;
        break;
        //SuperPackets
        case outputSuperPacket_mh:
            return DAQ.getOutputSuperPacketLength();
        break;
        case inputSuperPacket_mh:
            return DAQ.getInputSuperPacketLength();
        break;
        case actuatorSuperPacket_mh:
            return DAQ.getActuatorSuperPacketLength();
        break;

    }
    //for whatever reason I cannot get the default keyword to be recognized so here is a catch all
    return 0;	//bad message header

}

uint8_t DAQALLOC::getActuatorSuperPacketLength()
{
    uint8_t val = 4;//header + msg header + checksum1 + checksum2

    uint8_t inc;

    for(inc=0;inc<4;inc++)
    {
        //determine what motors and servos are enable
        //increment val accordingly
        if(this->motor[inc].enable) val += 2;
        if(this->servo[inc].enable) val += 2;
    }

    return val;
}

uint8_t DAQALLOC::getInputSuperPacketLength()
{
    uint8_t val = 4;//header + msg header + checksum1 + checksum2

    uint8_t inc;


    //ANALOG IN
    for(inc=0;inc<4;inc++)
    {
        if(this->analogIn[inc].enable) val += 2;
    }

    //ENCODERS
    for(inc=0;inc<2;inc++)
    {
        if(this->encoder[inc].enable)
        {
            //absolute encoders only use 2 bytes while inc are given 4
            if(this->encoder[inc].absolute) val += 2;
            else val += 4;
        }
    }

    //DIGITAL IN
    if(this->digital.inEnable) val +=2;

    return val;
}

uint8_t DAQALLOC::getOutputSuperPacketLength()
{
    uint8_t val = 4;//header + msg header + checksum1 + checksum2

    uint8_t inc;

    for(inc=0;inc<2;inc++)
    {
        if(this->analogOut[inc].enable) val +=2;
    }

    if(this->digital.outEnable) val += 4;

    return val;
}
